import os
import sys
import subprocess
import platform
import time
import shutil

def run_command(command, cwd=None):
    """
    运行命令行命令并返回执行结果
    
    Args:
        command: 要执行的命令列表
        cwd: 工作目录
        
    Returns:
        tuple: (返回码, 标准输出, 标准错误)
    """
    print(f"执行命令: {' '.join(command)}")
    try:
        # 执行命令
        result = subprocess.run(
            command,
            cwd=cwd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            shell=platform.system() == 'Windows'
        )
        return result.returncode, result.stdout, result.stderr
    except Exception as e:
        print(f"执行命令时出错: {e}")
        return 1, "", str(e)


# 清理目录函数
def clean_directory(dir_path):
    """清理指定目录中的所有文件和子目录"""
    if os.path.exists(dir_path):
        print(f"正在清理目录: {dir_path}")
        shutil.rmtree(dir_path)
    os.makedirs(dir_path, exist_ok=True)
    print(f"目录已创建: {dir_path}")


def main():
    """
    主函数，执行测试并生成Allure报告
    """
    # 初始化测试和报告的返回码变量
    cmd_returncode = 0  # 测试执行的返回码
    report_returncode = 0  # 报告生成的返回码
    
    # 获取当前目录
    current_dir = os.path.dirname(os.path.abspath(__file__))
    
    # 清理allure-results目录
    allure_results_dir = os.path.join(current_dir, "allure-results")
    clean_directory(allure_results_dir)
    
    # 步骤1：运行测试并生成allure结果
    print("="*50)
    print("开始运行测试...")
    # 构建测试目录路径，指向整个test_cases文件夹
    test_dir_path = os.path.join(current_dir, "test_cases")
    cmd = [sys.executable, "-m", "pytest", test_dir_path, "--alluredir=allure-results"]
    cmd_returncode, stdout, stderr = run_command(cmd, current_dir)
    
    print("\n测试输出:\n")
    print(stdout)
    if stderr:
        print("\n错误输出:\n")
        print(stderr)
    
    # 检查测试是否成功运行
    if cmd_returncode != 0:
        print("="*50)
        print("测试执行失败！")
    else:
        print("="*50)
        print("测试执行成功！")
    
    # 步骤2：生成allure报告（无论测试成功或失败）
    print("="*50)
    print("开始生成Allure报告...")
    cmd = ["allure", "generate", "allure-results", "-o", "allure-report", "--clean"]
    returncode, stdout, stderr = run_command(cmd, current_dir)
    
    print("\n报告生成输出:\n")
    print(stdout)
    if stderr:
        print("\n错误输出:\n")
        print(stderr)
    
    # 保存报告生成的返回码，但不立即退出
    report_returncode = returncode
    
    # 检查报告是否成功生成
    if report_returncode != 0:
        print("="*50)
        print("报告生成失败！")
        print("请确保已正确安装Allure命令行工具并添加到系统PATH环境变量中")
    
    print("="*50)
    print("Allure报告生成成功！")
    
    # 步骤3：打开allure报告
    print("="*50)
    print("开始打开Allure报告...")
    
    # 根据操作系统选择不同的打开方式
    if platform.system() == "Windows":
        # Windows系统
        cmd = ["allure", "open", "allure-report"]
    else:
        # 其他系统（如Linux、macOS）
        cmd = ["allure", "open", "allure-report"]
    
    # 异步运行打开报告的命令，不等待其完成
    try:
        subprocess.Popen(cmd, cwd=current_dir, shell=platform.system() == 'Windows')
        # 给浏览器一点时间来打开报告
        time.sleep(2)
        print("Allure报告已在浏览器中打开！")
    except Exception as e:
        print(f"打开报告时出错: {e}")
        print("\n您可以手动使用以下命令打开报告:")
        print(f"allure open {os.path.join(current_dir, 'allure-report')}")
    
    print("="*50)
    print("测试流程已完成！")
    input("按Enter键退出...")
    
    # 最终根据测试和报告生成的状态决定退出码
    # 如果测试失败但报告生成成功，返回测试的失败码
    if cmd_returncode != 0:
        sys.exit(cmd_returncode)
    # 如果报告生成失败，返回报告生成的失败码
    elif report_returncode != 0:
        sys.exit(report_returncode)
    # 全部成功，返回0
    else:
        sys.exit(0)


if __name__ == "__main__":
    main()